<?php
/*
 *  Jiba: A small collection of classes to make php easier.
 *  Copyright (C) 2007  Dimitri Michaux <dimitri.michaux@gmail.com>
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * appointment.class.php, Jiba
 * 
 * Generates a calendar for a given month (or several calendars) using
 * PHP Calendar (version 2.3), written by Keith Devens. With the added
 * functionallity to keep events.
 *
 * @author Dimitri Michaux
 * @version 0.1
 * @package jiba
 */

class Calendar {
  
  private $_events = array();
  
  public function addEvent( $month, $day, $year, $title, $description )
  {
    $this->_events[$year][$month][$day][] = array( 'title'       => $title,
                                                   'description' => $description );
  }
  
  public function printCalendars( $month=0, $year=0, $amount=3 )
  {
    if( $year == 0 )
      $year = date("Y");
    
    if( $month == 0 )
      $month = date("n")-1;
    else
      $month--;
    
    if( $day==0 )
      $day   = date('d', time() );
    
    if( $amount <= 0 )
      $amount = 1;
    
    $ret = "";
    
    //collect all events
    for( $i=0 ; $i<$amount ; $i++ )
    {
      if( $month > 12 )
      {
        $month-=12;
        $year++;
      }
      
      $days = array();
      if( is_array($this->_events[$year][$month]) )
      {
        //get all the events for this month per day
        foreach( $this->_events[$year][$month] as $day => $events )
        {
          $titles = "<span><b><a href=\"calendar.php?y=$year&m=$month&d=$day\">$day</a></b><ul>";
          if( is_array( $events ) )
          {
            //all the events for this day
            foreach( $events as $event )
            {
              $titles.= "<li>{$event['title']}</li>\n";
            }
            $titles.= "</ul></span>";
          }
          $days[$day] = array(NULL,NULL,$titles);
        }
      }
      //add the events to the calendar
      $ret.= "<td>\n".$this->generate_calendar( $year, $month, $days )."</td>\n";
      $month++;
    }
    
    return $ret;
  }

  # PHP Calendar (version 2.3), written by Keith Devens
  # http://keithdevens.com/software/php_calendar
  #  see example at http://keithdevens.com/weblog
  # License: http://keithdevens.com/software/license
  
  private function generate_calendar($year, $month, $days = array(), $day_name_length = 3, $month_href = NULL, $first_day = 0, $pn = array()){
          $first_of_month = gmmktime(0,0,0,$month,1,$year);
          #remember that mktime will automatically correct if invalid dates are entered
          # for instance, mktime(0,0,0,12,32,1997) will be the date for Jan 1, 1998
          # this provides a built in "rounding" feature to generate_calendar()
  
          $day_names = array(); #generate all the day names according to the current locale
          for($n=0,$t=(3+$first_day)*86400; $n<7; $n++,$t+=86400) #January 4, 1970 was a Sunday
                  $day_names[$n] = ucfirst(gmstrftime('%A',$t)); #%A means full textual day name
  
          list($month, $year, $month_name, $weekday) = explode(',',gmstrftime('%m,%Y,%B,%w',$first_of_month));
          $weekday = ($weekday + 7 - $first_day) % 7; #adjust for $first_day
          $title   = htmlentities(ucfirst($month_name)).'&nbsp;'.$year;  #note that some locales don't capitalize month and day names
  
          #Begin calendar. Uses a real <caption>. See http://diveintomark.org/archives/2002/07/03
          @list($p, $pl) = each($pn); @list($n, $nl) = each($pn); #previous and next links, if applicable
          if($p) $p = '<span class="calendar-prev">'.($pl ? '<a href="'.htmlspecialchars($pl).'">'.$p.'</a>' : $p).'</span>&nbsp;';
          if($n) $n = '&nbsp;<span class="calendar-next">'.($nl ? '<a href="'.htmlspecialchars($nl).'">'.$n.'</a>' : $n).'</span>';
          $calendar = '<table class="calendar">'."\n".
                  '<caption class="calendar-month">'.$p.($month_href ? '<a href="'.htmlspecialchars($month_href).'">'.$title.'</a>' : $title).$n."</caption>\n<tr>";
  
          if($day_name_length){ #if the day names should be shown ($day_name_length > 0)
                  #if day_name_length is >3, the full name of the day will be printed
                  foreach($day_names as $d)
                          $calendar .= '<th abbr="'.htmlentities($d).'">'.htmlentities($day_name_length < 4 ? substr($d,0,$day_name_length) : $d)."</th>";
                  $calendar .= "</tr>\n<tr>";
          }
  
          if($weekday > 0) $calendar .= '<td colspan="'.$weekday.'">&nbsp;</td>'."\n"; #initial 'empty' days
          for($day=1,$days_in_month=gmdate('t',$first_of_month); $day<=$days_in_month; $day++,$weekday++){
                  if($weekday == 7){
                          $weekday   = 0; #start a new week
                          $calendar .= "</tr>\n<tr>";
                  }
                  if(isset($days[$day]) and is_array($days[$day])){
                          @list($link, $classes, $content) = $days[$day];
                          if(is_null($content))  $content  = $day;
                          $calendar .= '<td'.($classes ? ' class="'.htmlspecialchars($classes).'">' : '>').
                                  ($link ? '<a href="'.htmlspecialchars($link).'">'.$content.'</a>' : $content).'</td>'."\n";
                  }
                  else $calendar .= "<td>$day</td>";
          }
          if($weekday != 7) $calendar .= '<td colspan="'.(7-$weekday).'">&nbsp;</td>'; #remaining "empty" days
  
          return $calendar."</tr>\n</table>\n";
  }
}
?>
